package com.cloud.cop.impl;

import java.util.Locale;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;

import com.cloud.cop.CopResponse;
import com.cloud.cop.CopResponseMarshaller;
import com.cloud.cop.CopServiceContext;
import com.cloud.cop.CopServiceHandlerRegistry;
import com.cloud.cop.CopServiceMethodAdapter;
import com.cloud.cop.CopServiceRouter;
import com.cloud.cop.ResponseFormat;
import com.cloud.cop.marshaller.JacksonJsonCopResponseMarshaller;
import com.cloud.cop.marshaller.JaxbXmlCopResponseMarshaller;
import com.cloud.cop.validation.MainErrors;
import com.cloud.cop.validation.SubErrors;

/**
 * <pre>
 * 		服务路由的实现类
 * </pre> 
 * @author mayh
 *
 */
@Controller
public class DefaultCopServiceRouter extends ApplicationObjectSupport implements CopServiceRouter {
	
	//是否执行了初始化
	private boolean isInit = false;
	private CopServiceHandlerRegistry copServiceHandlerRegistry;
	private CopServiceMethodAdapter copServiceMethodAdapter;
	private CopResponseMarshaller copResponseMarshallerJson = new JacksonJsonCopResponseMarshaller();
	private CopResponseMarshaller copResponseMarshallerXml = new JaxbXmlCopResponseMarshaller();
	private static final String METHOD = "method";
	private static final String LOCALE = "locale";
	private static final String FORMAT = "format";
	private static final String SESSIONID = "sessionId";
	private static final String APPKEY = "appKey";
	
	@RequestMapping("/router")
	public void service(WebRequest webRequest, HttpServletResponse response) {
		init();
		//创建服务上下文
		CopServiceContext copServiceContext = buildCopServiceContext(webRequest);
		CopResponse copResponse =  doService(copServiceContext);
		copServiceContext.setCopResponse(copResponse);
		writeCopResponse(copServiceContext,response);
	}
	
	public CopResponse doService(CopServiceContext copServiceContext){
		CopResponse copResponse = null;
		if(copServiceContext.getMethod()!=null){
			copResponse = copServiceMethodAdapter.invokeServiceMethod(copServiceContext);
		}
		return copResponse;
	}
	
	//写返回值
	private void  writeCopResponse(CopServiceContext context,HttpServletResponse response){
		try{
			response.setCharacterEncoding("UTF-8");
			if(context.getResponseFormat()==ResponseFormat.XML){
				response.setContentType("application/xml");
				copResponseMarshallerXml.marshaller(context.getCopResponse(), response.getOutputStream());
			}else {
				response.setContentType("application/json");
				copResponseMarshallerJson.marshaller(context.getCopResponse(), response.getOutputStream());
			}
		}catch(Exception e){
			
		}
	}
	
	//创建
	public DefaultSimpleCopServiceContext buildCopServiceContext(WebRequest request){
		DefaultSimpleCopServiceContext simpleCopServiceContext = new DefaultSimpleCopServiceContext();
		simpleCopServiceContext.setMethod(request.getParameter(METHOD));
		simpleCopServiceContext.setCopServiceHandler(copServiceHandlerRegistry.getCopServiceHandler(request.getParameter(METHOD)));
		simpleCopServiceContext.setLocale(getLocale(request));
		simpleCopServiceContext.setResponseFormat(ResponseFormat.getFormat(request.getParameter(FORMAT)));
		simpleCopServiceContext.setWebRequest(request);
		simpleCopServiceContext.setSessionId(request.getSessionId());
		simpleCopServiceContext.setAppKey(request.getParameter(APPKEY));
		return simpleCopServiceContext;
	}
	
	//获得本地化
	public Locale getLocale(WebRequest request){
		if(request.getParameter(LOCALE)!=null){
			LocaleEditor localEditor = new LocaleEditor();
			localEditor.setAsText(request.getParameter(LOCALE));
			return (Locale)localEditor.getValue();
		}else {
			return Locale.SIMPLIFIED_CHINESE;
		}
	}
	
	//执行初始化，仅执行一次
	public void init(){
		if(!isInit){
			copServiceHandlerRegistry = new DefaultCopServiceHandlerRegistry(getApplicationContext());
			copServiceMethodAdapter = new DefaultCopServiceMethodAdapter();
			initMessageSource();
			isInit = true;
		}
	}
	
	//设置消息资源文件
	void initMessageSource(){
		MainErrors.setMessageSourceAccessor(getMessageSourceAccessor());
		SubErrors.setErrorMessageSourceAccessor(getMessageSourceAccessor());
	}
}
